from typing import Any, Callable, Dict, List, Optional, Tuple, Union

from OCC.Core.gp import gp_Dir, gp_Pnt
from pythreejs import (
    Button,
    Checkbox,
    Line,
    Points,
    ShaderMaterial,
)

def _add(vec1: List[float], vec2: List[float]) -> List[float]: ...
def _explode(edge_list: List[List[float]]) -> List[List[List[float]]]: ...
def _flatten(nested_dict: Dict[Any, Any]) -> List[Any]: ...
def format_color(r: int, g: int, b: int) -> str: ...
def _distance(v1: List[float], v2: List[float]) -> float: ...
def _bool_or_new(val: Union[bool, Dict[str, Any]]) -> bool: ...
def _opt(b1: Tuple[float, ...], b2: Tuple[float, ...]) -> Tuple[float, ...]: ...
def _shift(v: List[float], offset: List[float]) -> List[float]: ...
def _nice_number(value: float, round_: bool = False) -> float: ...
def _nice_bounds(
    axis_start: float, axis_end: float, num_ticks: int = 10
) -> Tuple[float, float, float]: ...

class Helpers:
    def __init__(self, bb_center: Tuple[float, float, float]) -> None: ...
    def _center(self, zero: bool = True) -> Tuple[float, float, float]: ...
    def set_position(self, position: Tuple[float, float, float]) -> None: ...
    def set_visibility(self, change: bool) -> None: ...
    def set_center(self, change: bool) -> None: ...

class Grid(Helpers):
    def __init__(
        self,
        bb_center: Optional[Tuple[float, float, float]] = None,
        maximum: int = 5,
        ticks: int = 10,
        colorCenterLine: str = "#aaa",
        colorGrid: str = "#ddd",
    ) -> None: ...
    def set_position(self, position: Tuple[float, float, float]) -> None: ...
    def set_visibility(self, change: bool) -> None: ...
    def set_rotation(self, rotation: Tuple[float, float, float, str]) -> None: ...

class Axes(Helpers):
    def __init__(
        self,
        bb_center: Tuple[float, float, float],
        length: int = 1,
        width: int = 3,
        display_labels: bool = False,
    ) -> None: ...
    def set_position(self, position: Tuple[float, float, float]) -> None: ...
    def set_visibility(self, change: bool) -> None: ...

class CustomMaterial(ShaderMaterial):
    def __init__(self, typ: str) -> None: ...
    @property
    def color(self) -> str: ...
    @color.setter
    def color(self, value: str) -> None: ...
    @property
    def alpha(self) -> float: ...
    @alpha.setter
    def alpha(self, value: float) -> None: ...
    def update(self, key: str, value: Any) -> None: ...

class BoundingBox:
    def __init__(self, objects: List[Any], tol: float = 1e-5) -> None: ...
    def _max_dist_from_center(self) -> float: ...
    def _max_dist_from_origin(self) -> float: ...
    def _bounding_box(self, obj: Any, tol: float = 1e-5) -> Tuple[float, ...]: ...
    def _bbox(self, objects: List[Any]) -> Tuple[float, ...]: ...
    def __repr__(self) -> str: ...

class NORMAL:
    SERVER_SIDE: int
    CLIENT_SIDE: int

class JupyterRenderer:
    def __init__(
        self,
        size: Tuple[int, int] = (640, 480),
        compute_normals_mode: int = ...,
        default_shape_color: str = ...,
        default_edge_color: str = ...,
        default_vertex_color: str = ...,
        pick_color: str = ...,
        background_color: str = "white",
    ) -> None: ...
    def create_button(
        self, description: str, tooltip: str, disabled: bool, handler: Callable
    ) -> Button: ...
    def create_checkbox(
        self, kind: str, description: str, value: bool, handler: Callable
    ) -> Checkbox: ...
    def remove_shape(self, *kargs: Any) -> None: ...
    def on_compute_change(self, change: Dict[str, Any]) -> None: ...
    def toggle_shape_visibility(self, *kargs: Any) -> None: ...
    def toggle_axes_visibility(self, change: Dict[str, Any]) -> None: ...
    def toggle_grid_visibility(self, change: Dict[str, Any]) -> None: ...
    def click(self, value: Any) -> None: ...
    def register_select_callback(self, callback: Callable) -> None: ...
    def unregister_callback(self, callback: Callable) -> None: ...
    def GetSelectedShape(self) -> Any: ...
    def DisplayShapeAsSVG(
        self,
        shp: Any,
        export_hidden_edges: bool = True,
        location: gp_Pnt = ...,
        direction: gp_Dir = ...,
        color: str = "black",
        line_width: float = 0.5,
    ) -> None: ...
    def DisplayShape(
        self,
        shp: Any,
        shape_color: Optional[str] = None,
        render_edges: bool = False,
        edge_color: Optional[str] = None,
        edge_deflection: float = 0.05,
        vertex_color: Optional[str] = None,
        quality: float = 1.0,
        transparency: bool = False,
        opacity: float = 1.0,
        topo_level: str = "default",
        update: bool = False,
        selectable: bool = True,
    ) -> None: ...
    def AddVerticesToScene(
        self, pnt_list: List[gp_Pnt], vertex_color: str, vertex_width: int = 5
    ) -> Points: ...
    def AddCurveToScene(self, shp: Any, edge_color: str, deflection: float) -> Line: ...
    def AddShapeToScene(
        self,
        shp: Any,
        shape_color: Optional[str] = None,
        render_edges: bool = False,
        edge_color: Optional[str] = None,
        vertex_color: Optional[str] = None,
        quality: float = 1.0,
        transparency: bool = False,
        opacity: float = 1.0,
    ) -> Any: ...
    def _scale(self, vec: List[float]) -> List[float]: ...
    def _material(
        self, color: str, transparent: bool = False, opacity: float = 1.0
    ) -> CustomMaterial: ...
    def EraseAll(self) -> None: ...
    def Display(
        self,
        position: Optional[Tuple[float, float, float]] = None,
        rotation: Optional[Tuple[float, float, float]] = None,
    ) -> None: ...
    def ExportToHTML(self, filename: str) -> None: ...
    def _reset(self, *kargs: Any) -> None: ...
    def _update(self) -> None: ...
    def __repr__(self) -> str: ...
